Pilots A+B: comparison column was rendering in body ink (specificity) - #564
Merged
Conversation
…in body ink Both merged register pilots carry the specificity defect found while building pilot C: `.rr-table tbody td` scores 0,1,2 on its two tag names and beats the bare `.rr-td-muted` at 0,1,0 that layouts/next/landing.html puts on the full-time column. The muted tone IS the comparison - without it the two columns read as equally weighted and the table stops arguing anything. The CSS looks correct in source, which is why it shipped twice. One line each, the same scope change pilot C already uses: `.rr-td-muted` -> `.rr-table tbody .rr-td-muted`. Measured on PRODUCTION builds (baseURL pointed at a local origin so the browser renders the actually-purged bundle, not jetthoughts.com's), computed colour of all five "theirs" cells, before -> after: - pilot A rescue-room: rgb(61, 55, 51) #3d3733 (--rr-body) -> rgb(107, 98, 92) #6b625c (--rr-muted), 5.95:1 on its ground - pilot B editorial: rgb(69, 65, 61) #45413d (--ed-body) -> rgb(107, 101, 96) #6b6560 (--ed-muted), 5.74:1 on its ground Both were identical to their "ours" column before and are distinct from it after; both cuts still clear AA. The fixed selector survives PurgeCSS in both production bundles. Only ONE baseline moved. Pilot A's desktop capture reaches two tbody rows, so it failed at difference_level 0.0007 in region [1140, 991, 1351, 1064] - the "theirs" cells exactly - and is re-recorded here with that column visibly lighter than the one beside it. Pilot B's desktop capture stops at the table HEADER row, and the header was never affected (only tbody cells carry the class), so it is correctly unchanged rather than silently missed. Both mobile captures end above the table and stayed green; neither was re-recorded. Gates: bin/hugo-build clean; bin/rake test:unit 292 runs, 6164 assertions, 0 failures; all three pilots' desktop+mobile screenshot tests green post-commit (8 runs, 8 screenshots, 0 failures); banned-string sweep across the built pilots dir unchanged at zero matches, with the same grep still finding "Typically required" 3x to show it reads the files; pilot C untouched - zero changes to any precision file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Contributor
Screenshot diffs detected
|
pftg
added a commit
that referenced
this pull request
Aug 21, 2026
…nc (#565) Board carries the three live /next/ URLs, the four-persona ballots with self-objections, the Editorial 4-1 artifact head-to-head, the fable recommendation with its graft package, and the decision protocol - Paul picks. Ledger rows updated for #561-#564 and the #560 gate repair; OKF gains the BASE_URL local-production-check rule. Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
pftg
added a commit
that referenced
this pull request
Aug 22, 2026
Gate fault-injection audit: 3 of 8 defects caught Injected eight defects modelled on ones this repo has shipped, one at a time, each followed by the narrowest gate that should catch it. Predictions were written before any run; two were wrong and both are recorded as wrong. Caught: above-fold contrast (A), smoothed testimonial (C), lost noindex (E). Missed: below-fold visual (B), frozen tenure (D), banned phrase (F), the <th> purge trap (G), broken internal link (H). Two findings the predictions did not anticipate: - test:links checks almost nothing. The production build renders internal links absolute, and lychee --offline excludes all http(s) URIs, so 133,874 of 149,516 links are excluded; the homepage checks exactly one link, its own #main-content anchor. A --remap of the host onto the build dir was verified to catch the planted break. - MarketingCopyTest's rendered ratchet has three hits of slack (baseline 14, actual 11), which is what let the injected banned phrase through. Below-fold coverage quantified for task #12: the viewport-sized capture gates 28.3% of the editorial pilot (1080px of 3822px). The injected #564-class defect sits at y=1090 - ten pixels outside the frame. No baselines re-recorded; every injection reverted. Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
pftg
added a commit
that referenced
this pull request
Aug 22, 2026
…sted The 2026-08-22 audit planted eight defects and the suite caught three. Three of the five misses get gates here. Every one was injected, watched fail, reverted and watched pass - green alone proves a test runs, not that it works. D - a frozen tenure number. The rendered assertion cannot tell `derived` from `frozen` while both read "18+" in 2026, and saying so in the test body is honest but guards nothing. The freeze is plainly visible one layer down, so NextRailTest now asserts both halves: the rendered value, and that every pilot stub carries `derived: tenure` with no stat frozen at today's derived string. Not a config test - the hardcoded literal IS the defect class, the way the 2026-08-14 canon audit found the founding year wrong in eight places because each kept its own copy. G - the PurgeCSS trap the audit called unguardable. It is unguardable by the VISUAL gate, which builds production and so purges exactly as production does, matching its own baseline. It is trivially visible to a set diff: styled in the register's source CSS, present on an element in the rendered HTML, absent from the bundle the page links. next_purge_guard_test.rb is keyed on that mechanism rather than on `th`, so the next element type Hugo stops recording is covered without an edit, and it reads the bundle from the page's own href - stale fingerprinted bundles sit in the same directory. B and the contrast hole - computed styles, not per-band screenshots. The audit's own recommendation buys four more baselines per pilot, each needing its noise floor measured on the platform that judges it, and still returns a pixel delta rather than a ratio - so an intentional recolour and an AA regression stay indistinguishable. next_pilot_contrast_test.rb asserts the comparison table's "theirs" column computes the register's own --*-muted token, then walks every visible text run for 4.5:1 (3:1 large, SC 1.4.3) and every control fill for 3:1 against its surround (SC 1.4.11). ~1.3s for three pages, no baselines, wired into test:critical. It closes the hole the audit flagged separately: nothing in this suite measured contrast as a number, and a 3.33:1 black-on-ruby button shipped this rail on human review alone. One mistake worth keeping. The muted-column assertion was first written as "differs from the sibling cell and from body colour" and PASSED the exact #564 injection - in that register the "ours" column IS body colour and the injected ink is a third value. Wrong for two runs, green both times; only the injection said so. Injections and failures, all reverted before the next: D `derived: tenure` -> `value: "18+"` the tenure stat must be `derived: tenure` so layouts/next/landing.html computes it from site.Params.foundingYear D a second stat frozen at "18+" alongside the derived one Expected ["Years of average developer experience"] to be empty G class="rr-th-theirs" on a <th> + a matching rule Expected ["rr-th-theirs"] to be empty control: the SAME class moved onto the <td> in that row goes green, so it flags the purge and not merely a new class B .rr-td-muted -> var(--ed-ink), below the fold computes rgb(27, 28, 28), not --ed-muted (rgb(107, 101, 96)). It resolves to --ed-ink A .rr-btn-primary label -> var(--ed-ink) on the accent fill 2.31:1 (needs 4.5:1) text a.rr-btn.rr-btn-primary A' .rr-td-muted -> #b5b0ab, below the fold - invisible to every screenshot 2.15:1 (needs 4.5:1) on five cells A" a near-paper button fill with a readable label 1.12:1 (needs 3.0:1) fill a.rr-btn.rr-btn-primary Each walk asserts it measured something (>50 text pairs, >0 fills, a non-empty styled-and-rendered set) - a walk that finds nothing is empty, and empty passes. Gates: test:unit 289 runs / 6187 assertions / 0 failures in 1.42s (287 / 6143 / 1.33s before - the purge guard reuses the build the suite already makes); test:critical 38 runs / 0 failures, 55 screenshots compared, no failures, no baseline rewritten; bin/hugo-build clean; standardrb clean on the new files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
pftg
added a commit
that referenced
this pull request
Aug 22, 2026
Close three fault-injection gaps: 8 of 8, each gate broken before trusted The 2026-08-22 audit planted eight defects and the suite caught three. Three of the five misses get gates here. Every one was injected, watched fail, reverted and watched pass - green alone proves a test runs, not that it works. D - a frozen tenure number. The rendered assertion cannot tell `derived` from `frozen` while both read "18+" in 2026, and saying so in the test body is honest but guards nothing. The freeze is plainly visible one layer down, so NextRailTest now asserts both halves: the rendered value, and that every pilot stub carries `derived: tenure` with no stat frozen at today's derived string. Not a config test - the hardcoded literal IS the defect class, the way the 2026-08-14 canon audit found the founding year wrong in eight places because each kept its own copy. G - the PurgeCSS trap the audit called unguardable. It is unguardable by the VISUAL gate, which builds production and so purges exactly as production does, matching its own baseline. It is trivially visible to a set diff: styled in the register's source CSS, present on an element in the rendered HTML, absent from the bundle the page links. next_purge_guard_test.rb is keyed on that mechanism rather than on `th`, so the next element type Hugo stops recording is covered without an edit, and it reads the bundle from the page's own href - stale fingerprinted bundles sit in the same directory. B and the contrast hole - computed styles, not per-band screenshots. The audit's own recommendation buys four more baselines per pilot, each needing its noise floor measured on the platform that judges it, and still returns a pixel delta rather than a ratio - so an intentional recolour and an AA regression stay indistinguishable. next_pilot_contrast_test.rb asserts the comparison table's "theirs" column computes the register's own --*-muted token, then walks every visible text run for 4.5:1 (3:1 large, SC 1.4.3) and every control fill for 3:1 against its surround (SC 1.4.11). ~1.3s for three pages, no baselines, wired into test:critical. It closes the hole the audit flagged separately: nothing in this suite measured contrast as a number, and a 3.33:1 black-on-ruby button shipped this rail on human review alone. One mistake worth keeping. The muted-column assertion was first written as "differs from the sibling cell and from body colour" and PASSED the exact #564 injection - in that register the "ours" column IS body colour and the injected ink is a third value. Wrong for two runs, green both times; only the injection said so. Injections and failures, all reverted before the next: D `derived: tenure` -> `value: "18+"` the tenure stat must be `derived: tenure` so layouts/next/landing.html computes it from site.Params.foundingYear D a second stat frozen at "18+" alongside the derived one Expected ["Years of average developer experience"] to be empty G class="rr-th-theirs" on a <th> + a matching rule Expected ["rr-th-theirs"] to be empty control: the SAME class moved onto the <td> in that row goes green, so it flags the purge and not merely a new class B .rr-td-muted -> var(--ed-ink), below the fold computes rgb(27, 28, 28), not --ed-muted (rgb(107, 101, 96)). It resolves to --ed-ink A .rr-btn-primary label -> var(--ed-ink) on the accent fill 2.31:1 (needs 4.5:1) text a.rr-btn.rr-btn-primary A' .rr-td-muted -> #b5b0ab, below the fold - invisible to every screenshot 2.15:1 (needs 4.5:1) on five cells A" a near-paper button fill with a readable label 1.12:1 (needs 3.0:1) fill a.rr-btn.rr-btn-primary Each walk asserts it measured something (>50 text pairs, >0 fills, a non-empty styled-and-rendered set) - a walk that finds nothing is empty, and empty passes. Gates: test:unit 289 runs / 6187 assertions / 0 failures in 1.42s (287 / 6143 / 1.33s before - the purge guard reuses the build the suite already makes); test:critical 38 runs / 0 failures, 55 screenshots compared, no failures, no baseline rewritten; bin/hugo-build clean; standardrb clean on the new files. Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One-line scope fix per file:
.rr-td-muted(0,1,0) lost to.rr-table tbody td(0,1,2), so both merged pilots' "Full-time CTO" columns rendered identical to the "ours" column — the comparison table stopped comparing. Found by pilot C's author (C shipped with the fix), confirmed on master by C's verifier with computed colors and a generalized detector (A=1, B=1, C=0 hits).Fix:
.rr-table tbody .rr-td-muted(0,2,0). Computed before→after on true production bundles (BASE_URL-local, own fingerprinted CSS confirmed loading): A#3d3733→#6b625c(5.95:1), B#45413d→#6b6560(5.74:1), all five rows each.One baseline re-recorded (A desktop — the only capture whose frame reaches tbody rows; B's stops at the header, verified by reading the PNG). The failing diff was 0.0007 — silently green under the pre-#560 tolerance. Unit 292/6164/0; all three pilots' scoped screenshots 8/8 green; pilot C untouched.
Demo-relevant: without this, registers A and B misrepresent themselves on the lightning-demo board.
🤖 Generated with Claude Code
https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ